package com.liangtian.mdm.dm.attribute.service.impl;

import com.liangtian.mdm.base.dao.JdbcDao;
import com.liangtian.mdm.dm.attribute.dao.AttributeDao;
import com.liangtian.mdm.dm.attribute.model.Attribute;
import com.liangtian.mdm.dm.attribute.service.AttributeService;
import com.liangtian.mdm.dm.common.constant.TableConst;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import com.liangtian.mdm.dm.jsp.common.ExcelUtil;
import com.liangtian.mdm.dm.listener.CacheUtil;
import com.liangtian.mdm.dm.model.dao.ModelDao;
import com.liangtian.mdm.dm.model.model.Model;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.xssf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class AttributeServiceImp implements AttributeService {
    //日志
    private static final Logger logger = LoggerFactory.getLogger(AttributeServiceImp.class);

    //注入dao
    @Autowired
    AttributeDao attributeDao;

    @Autowired
    private ModelDao modelDao;

    @Autowired
    private JdbcDao jdbcDao;

    //注入缓存CacheUtil
    @Autowired
    private CacheUtil cacheUtil;

    /**
     * 初始化属性 类型
     */
    private Map<String, String> typeMap = new HashMap<String, String>() {{
        put("字符", "VARCHAR2");
        put("整数", "NUMBER");
        put("小数", "NUMBERM");
        put("日期", "DATE");
        put("文件域", "BLOB");
        put("文本域", "CLOB");
    }};

    /**
     * 属性列表页面数据查询
     */
    @Override
    public List<Attribute> queryAll(Attribute attribute) {
        List<Attribute> lst = attributeDao.selectAttributePageByCondition(attribute.getModelId());
        return lst;
    }

    /**
     * <p>TODO 删除属性字段（1.需要清除缓存，2.属性列表本属性需要删除及属性设置和视图设置需要删除
     * 3.已经生成的表中也需要把此属性drop掉）</p>
     * 2017/06/09 12:32周五
     * 更改了属性逻辑删除功能，删除就是删除（逻辑删除改成物理删除）
     * <p>@param request
     * <p>@param attrIds
     * <p>@param modelId
     * <p>@return </p>
     *
     * @author : xiaoliu
     * @date :2017年6月9日上午11:21:12
     */
    @Override
    public int batchDelAttr(String[] ids, String modelId) {
        Map<String, Object> map = new HashMap<>();
        List<String> idsLst = Arrays.asList(ids);
        Model model = modelDao.selectByPk(modelId); //判断这个模型是否已经创建表
        if (1 == model.getIsTableCreate()) {  //已经创建了表
            //attributeDao.updateAttributeIsDel(idsLst);  //逻辑删除
            Attribute attr = attributeDao.selectAttributeById(idsLst.get(0));
            this.updateTableColumn(attr, attr.getAttrColumn(), "del"); //删除列
            //物理删除属性
//				map.remove("modelId");
//				map.put("idsList", idsLst);
//			    attributeDao.batchDeleteAttrubute(map);
        }
        //else{  //没有创建表物理删除
        map.remove("modelId");
        map.put("idsList", idsLst);
        attributeDao.batchDeleteAttrubute(map);
        //}
        return 1;
    }

    /**
     * 新增
     */
    @Override
    public void attrAdd(Attribute attribute) {
        String cloumnName = this.getColumnIndex(attribute.getModelId() + "", null);
        attribute.setAttrColumn(cloumnName);  //获取列名 C_001  C_002
        if ("NUMBER".equals(attribute.getDataType())) {  //整数
            attribute.setAttrLength(attribute.getAttrLength());//将整数位长度赋值给字符长度，用于前台展示
        } else if ("NUMBERM".equals(attribute.getDataType())) { //小数
            attribute.setAttrLength(attribute.getAttrZs() + "," + attribute.getAttrXs());//将整数位长度和小数位长度赋值给字符长度，用于前台展示
        }
        attributeDao.insertAttrubute(attribute);
        this.updateTableColumn(attribute, cloumnName, "add");
    }

    /**
     * <p>TODO  对于已经创建表的模型做如下操作：</p>
     * 1.新增的话
     * <p>@param attribute
     * <p>@param columnName
     * <p>@param operType </p>
     *
     * @author : xiaoliu
     * @date :2017年6月9日上午11:34:48
     */
    private void updateTableColumn(Attribute attribute, String columnName, String operType) {
        Model model = modelDao.selectByPk(attribute.getModelId());
        // 生成注释sql
        //List<String> comments = new ArrayList<>();
        String isCreateTable = model.getIsTableCreate() + "";
        if ("1".equals(isCreateTable)) { //已经创建了表 更新表
            //cacheUtil.removeElement(attribute.getModelId());
            List<String> sqlLst = new ArrayList<String>();
            StringBuffer alertTableSb = new StringBuffer();
            StringBuffer alertUpdateTableSb = new StringBuffer();
            StringBuffer updateConfig = new StringBuffer();
            StringBuffer delConfig = new StringBuffer();
            StringBuffer addcomments = new StringBuffer();
            StringBuffer discomments = new StringBuffer();
            StringBuffer updatecomments = new StringBuffer();

            if ("add".equals(operType)) {//新增属性
                alertTableSb.append("alter table T_").append(attribute.getModelId()).append(" add " + columnName + " " +
                        "VARCHAR2(" + dbLength(attribute) + ")");
                //添加注释
                addcomments.append("COMMENT ON COLUMN T_" + attribute.getModelId() + "." + columnName + " IS '"
                        + nvl(attribute.getAttrName(), attribute.getAttrDesc()) + "'");
                updateConfig.append("insert into AM_ATTR_CONFIG (id, model_id, attr_id, attr_type, SHOW_ORDER, GROUP_ORDER, GROUP_ID) "
                        + "select AM_ATTR_CONFIG_SEQ.nextval, tmp.*, 100, 0, ''  from ( "
                        + "select model_id, id, data_type from AM_ATTRIBUTE where model_id = " + attribute.getModelId() + " and attr_column='" + columnName + "' order by id ) tmp ");
            } else if ("del".equals(operType)) {//删除
                alertTableSb.append("alter table T_").append(attribute.getModelId()).append(" drop column " + columnName);
                delConfig.append("delete from AM_ATTR_CONFIG where model_id='" + attribute.getModelId() + "' " + "and attr_id='" + attribute.getId() + "'");
            } else if ("edit".equals(operType)) {//编辑
                updateConfig.append("update AM_ATTRIBUTE set attr_name='" + attribute.getAttrName() + "',attr_length ='" + attribute.getAttrLength() + "' where model_id='" + attribute.getModelId() + "' " + "and id='" + attribute.getId() + "'");
                alertTableSb.append("alter table T_").append(attribute.getModelId()).append(" modify " + columnName + " " +
                        "VARCHAR2(" + dbLength(attribute) + ")");
            }

            String modelType = model.getModelType();
            //针对变更表所做的操作
            //针对分发表所做的操作
            if ("0".equals(modelType)) { //主数据类型
                StringBuffer alertDisTableSb = new StringBuffer();
                if ("add".equals(operType)) {
                    alertUpdateTableSb.append("alter table T_").append(attribute.getModelId() + "_update").append(" add " + columnName + " " +
                            "VARCHAR2(" + dbLength(attribute) + ")");
                    //添加注释
                    updatecomments.append("COMMENT ON COLUMN T_" + attribute.getModelId() + "_update." + columnName + " IS '"
                            + nvl(attribute.getAttrName(), attribute.getAttrDesc()) + "'");
                    alertDisTableSb.append("alter table T_").append(attribute.getModelId() + "_dis").append(" add " + columnName + " " +
                            "VARCHAR2(" + dbLength(attribute) + ")");
                    //添加注释
                    discomments.append("COMMENT ON COLUMN T_" + attribute.getModelId() + "_dis." + columnName + " IS '"
                            + nvl(attribute.getAttrName(), attribute.getAttrDesc()) + "'");
                } else if ("del".equals(operType)) {
                    alertUpdateTableSb.append("alter table T_").append(attribute.getModelId() + "_update").append(" drop column " + columnName);
                    alertDisTableSb.append("alter table T_").append(attribute.getModelId() + "_dis").append(" drop column " + columnName);
                } else if ("edit".equals(operType)) {
                    alertUpdateTableSb.append("alter table T_").append(attribute.getModelId() + "_update ").append(" modify " + columnName + " " +
                            "VARCHAR2(" + dbLength(attribute) + ")");
                    alertDisTableSb.append("alter table T_").append(attribute.getModelId() + "_dis ").append(" modify " + columnName + " " +
                            "VARCHAR2(" + dbLength(attribute) + ")");
                }
                sqlLst.add(alertDisTableSb + "");
            }

            //统一提交
            //jdbcDao.executeSqlList(comments, true);
            sqlLst.add(alertTableSb + "");
            sqlLst.add(alertUpdateTableSb + "");
            sqlLst.add(updateConfig + "");
            sqlLst.add(delConfig + "");
            sqlLst.add(addcomments + "");
            sqlLst.add(updatecomments + "");
            sqlLst.add(discomments + "");
            boolean ret = jdbcDao.executeSqlList(sqlLst, true);
            System.err.println(ret);
            if (ret) {
                cacheUtil.removeElement(attribute.getModelId());//清除属性列表缓存
                cacheUtil.removeAttrConfig(attribute.getModelId());//清除属性设置缓存缓存
                cacheUtil.removeQueryCols(attribute.getModelId());//清除查询列缓存缓存
            }
        }
    }

    private String dbLength(Attribute attr) {
        String len = attr.getAttrLength();
        if (len == null) {
            //文本
            if (attr.getDataType() != null && "CLOB".equals(attr.getDataType()))
                len = "4000";
                //文件存储路径
            else if (attr.getDataType() != null && "BLOB".equals(attr.getDataType()))
                len = "200";
            else // 日期
                len = "20";
        } else {
            String[] ls = len.split(",");
            if (ls.length > 1) {
                //整数+小数+小数点
                len = (Integer.parseInt(ls[0]) + Integer.parseInt(ls[1]) + 1) + "";
            }
        }
        return len;
    }

    private String nvl(String val1, String val2) {
        String val = val1;
        if (val1 == null || "".equals(val1))
            val = val2;
        if (val == null)
            val = "";
        return val;
    }

    /**
     * 获取最大的列加1生成新的列名
     *
     * @param modelId
     * @return
     */
    private String getColumnIndex(String modelId, String maxColumn) {
        String max = attributeDao.selectColumnIndexByModelId(modelId);  //获得最大的编号
        int Fmax = 1;
        String column = null;
        if (null != maxColumn) {
            String max1 = maxColumn.split("_")[1];
            int target = Integer.valueOf(max1);
            if (null != max) {
                Fmax = Integer.valueOf(max) > target ? Integer.valueOf(max) : target;
            } else {
                if (target < 9) {
                    column = TableConst.COLUMNPREFIX + "00" + (target + 1);
                } else if (target < 98) {
                    column = TableConst.COLUMNPREFIX + "0" + (target + 1);
                } else {
                    column = TableConst.COLUMNPREFIX + (target + 1);
                }
            }
        } else {
            if (null != max)
                Fmax = Integer.valueOf(max);
        }
        if (null == column) {
            column = TableConst.COLUMNPREFIX + "001";
        }

        if (null != max) {
            if (Fmax < 9) {
                column = TableConst.COLUMNPREFIX + "00" + (Fmax + 1);
            } else if (Fmax < 98) {
                column = TableConst.COLUMNPREFIX + "0" + (Fmax + 1);
            } else {
                column = TableConst.COLUMNPREFIX + (Fmax + 1);
            }
        }
        return column;
    }

    /**
     * 校验同一模型属性名称重复
     *
     * @param
     * @return
     */
    @Override
    public int checkAttrName(Attribute attribute) {
        Map<String, Object> map = new HashMap<>();
        map.put("modelId", attribute.getModelId());
        map.put("attrName", attribute.getAttrName());
        return attributeDao.checkAttrName(map);
    }

    /**
     * 编辑
     */
    @Override
    public int editAttr(Attribute attribute) {
		/*if("NUMBER".equals(attribute.getDataType())){  //整数
			attribute.setAttrLength(attribute.getAttrZs()+"");//将整数位长度赋值给字符长度，用于前台展示
		}else */
        if ("NUMBERM".equals(attribute.getDataType())) { //小数
            attribute.setAttrLength(attribute.getAttrZs() + "," + attribute.getAttrXs());//将整数位长度和小数位长度赋值给字符长度，用于前台展示
        } else if ("CLOB".equals(attribute.getDataType()) || "BLOB".equals(attribute.getDataType()) || "DATE".equals(attribute.getDataType())) {//文本框，日期，附件
            attribute.setAttrLength("");
        }
        Model model = modelDao.selectByPk(attribute.getModelId());
        int count = attributeDao.updateAttribute(attribute);
        //Attribute attributeEdit = attributeDao.selectAttributeById(attribute.getId());
        this.updateTableColumn(attribute, attribute.getAttrColumn(), "edit");
        if ("1".equals(model.getIsTableCreate() + "")) { //已经创建了表 更新表
            cacheUtil.removeElement(attribute.getModelId());//清除属性列表缓存
            cacheUtil.removeAttrConfig(attribute.getModelId());//清除属性设置缓存缓存
            cacheUtil.removeQueryCols(attribute.getModelId());//清除查询列缓存缓存
        }

        return count;
        //return 1;
    }

    /**
     * 编辑时校验属性名称重复性
     */
    @Override
    public int checkAttrNameEdit(Attribute attribute) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", attribute.getId());
        map.put("modelId", attribute.getModelId());
        map.put("attrName", attribute.getAttrName().trim());
        return attributeDao.checkAttrNameEdit(map);
    }

    @Override
    public Attribute selectAttributeById(Attribute attribute) {
        return attributeDao.selectAttributeById(attribute.getId());
    }

    @Override
    public void attributeExport(HttpServletResponse resp) {
        try {
            OutputStream out = null;

            List<String[]> AttributeHeadLst = new ArrayList<String[]>();//属性列的集合
            String[] attrName = {"属性名称", "属性名称必填\n不能重复"};
            AttributeHeadLst.add(attrName);
            String[] attrType = {"属性数据类型", "属性类型必选"};
            AttributeHeadLst.add(attrType);
            String[] attrLen = {"属性长度", "属性数据类型选择为字符、整数、小数时,属性长度必填\n属性数据类型选择为小数时，属性长度的书写格式为：整数位长度+','+小数位长度。如:4,5\n属性类型选择为日期，属性长度不填"};//后期添加用户导出模板-（加了用户密码这项）
            AttributeHeadLst.add(attrLen);
            String[] des = {"属性描述", "不必填"};
            AttributeHeadLst.add(des);

            XSSFWorkbook workbook = new XSSFWorkbook(); // 声明一个工作薄，开始将上一类别的数据写入到excel
            CreationHelper factory = workbook.getCreationHelper();
            XSSFSheet sheet = workbook.createSheet(); //声明一个工作薄的sheet页
            //sheet.setDefaultColumnWidth(50);
            //sheet.setDefaultRowHeight((short) (1 * 256));
            sheet.setDefaultColumnWidth(30);
            XSSFRow row = sheet.createRow(0); //创建这个sheet页的第一行
            XSSFCellStyle style = workbook.createCellStyle();
            XSSFCellStyle redStyle = workbook.createCellStyle();
            XSSFFont font = workbook.createFont();
            font.setBold(true);
            font.setColor(HSSFColor.HSSFColorPredefined.RED.getIndex());
            redStyle.setFont(font);

            for (int i = 0; i < AttributeHeadLst.size(); i++) {
                String[] typeLst = AttributeHeadLst.get(i);
                if ("属性数据类型".equals(typeLst[0])) {
                    List<String> attrTypeLst = new ArrayList<String>();
                    /*attrTypeLst.add("请选择");*/
                    attrTypeLst.add("字符");
                    attrTypeLst.add("整数");
                    attrTypeLst.add("小数");
                    attrTypeLst.add("日期");
                    attrTypeLst.add("文件域");
                    attrTypeLst.add("文本域");
                    ExcelUtil.addCell(sheet, row, AttributeHeadLst.get(i)[0], i, redStyle, attrTypeLst);
                } else {
                    if ("属性名称".equals(typeLst[0]) || "属性长度".equals(typeLst[0])) {
                        ExcelUtil.addCell(sheet, row, AttributeHeadLst.get(i)[0], i, redStyle, null);
                    } else {
                        ExcelUtil.addCell(sheet, row, AttributeHeadLst.get(i)[0], i, style, null);
                    }
                }
            }

            workbook.setSheetName(0, "属性通用模板");
            XSSFSheet sheet1 = workbook.createSheet(); //声明一个工作薄的sheet页
            sheet1.setDefaultColumnWidth(100);
            workbook.setSheetName(1, "属性模板填写说明");
            XSSFRow row1 = sheet1.createRow(0); //创建这个sheet页的第一行
            String nameStr = "属性名称不能为空，不能重复";
            ExcelUtil.addCell(sheet1, row1, nameStr, 0, style, null);

            XSSFRow row4 = sheet1.createRow(1); //创建这个sheet页的第三行
            String requeirStr = "属性类型选择为字符、整数、小数时,属性长度必填";
            ExcelUtil.addCell(sheet1, row4, requeirStr, 0, style, null);

            XSSFRow row2 = sheet1.createRow(2); //创建这个sheet页的第二行
            String xsStr = "属性类型选择为小数时，长度的填写格式为：整数位长度+','+小数位长度。如:4,5";
            ExcelUtil.addCell(sheet1, row2, xsStr, 0, style, null);
            XSSFRow row3 = sheet1.createRow(3); //创建这个sheet页的第三行
            String dateStr = "属性类型选择为日期，属性长度不必填";
            ExcelUtil.addCell(sheet1, row3, dateStr, 0, style, null);
			
			/*XSSFRow row4 = sheet1.createRow(3); //创建这个sheet页的第三行
			String lengthStr = "填写属性名称时长度不能超过属性长度";
			ExcelUtil.addCell(sheet,row4,lengthStr,0,style,null);*/

            out = resp.getOutputStream();
            ExcelUtil.setResponseHeader(resp, null);
            workbook.write(out);
            workbook.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Map<String, Object> attributeImport(String modelId, InputStream input) {
        Map<String, Object> result_map = new HashMap<>();
        boolean success = false;// 默认此次导入操作不成功
        ExcelUtil eu = new ExcelUtil();

        List<Map<Integer, Map<Integer, String>>> attrValueLst = ExcelUtil.excelImport2(input, modelId);   //返回的值和属性对应值的map集合
        if (null != attrValueLst) {//&& attrValueLst.size()>1
            //校验属性值
            result_map = check_sx(attrValueLst, modelId);
            if ((Boolean) result_map.get("bool")) {
                List<Attribute> resultList = (List<Attribute>) result_map.get("list");
                if (resultList.size() >= 1) {//如果有数据
                    //插入数据库
                    insert_sx(resultList, modelId);
                    success = true;
                } else {
                    String errText = "模板没有数据，请检查完，在操作！";
                    //String fileName="属性导入错误"+"@@@@"+new SimpleDateFormat("yyyyMMddHHmmssSSS") .format(new Date())+".txt";
                    //eu.errTxt(errText, errText);
                    //result_map.put("err_fileName", fileName);
                    success = false;
                    result_map.put("bool", success);
                    result_map.put("err_fileName", errText);
                }
            } else {
                try {
                    String errText = (String) result_map.get("error");
                    String fileName = "属性导入错误" + "@@@@" + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + ".txt";
                    eu.errTxt(errText, fileName);
                    result_map.put("err_fileName", fileName);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            result_map.put("bool", success);
        }
//		else{
//			try {
//				String errText="模板没有数据，请检查完，在操作！";
//				String fileName="属性导入错误"+"@@@@"+new SimpleDateFormat("yyyyMMddHHmmssSSS") .format(new Date())+".txt";
//				eu.errTxt(errText, fileName);
//				result_map.put("err_fileName", fileName);
//				result_map.put("bool", success);
//			} catch (IOException e) {
//				e.printStackTrace();
//			}
//		}

        return result_map;
    }

    private Map<String, Object> check_sx(List<Map<Integer, Map<Integer, String>>> attrValueLst, String modelId) {
        Map<String, Object> result_map = new HashMap<>();
        List<Attribute> rst = new ArrayList<Attribute>();
        boolean bool = true;
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < attrValueLst.size(); i++) {
            Map<Integer, Map<Integer, String>> map = attrValueLst.get(i);//获取到sheet页的所有行数据
            Map<Integer, String> firstRowMap = map.get(1);
            String value = null;
            String colValue = null;
            String dataType = null;
            String maxCol = null;
            Map<String, Object> sameMap = check_same(map);//检验excel是否有相同的属性名称
            if ((Boolean) sameMap.get("bool")) {
                Map<String, Object> checkMap = check(map, firstRowMap, modelId);//校验每个字段的格式
                if ((Boolean) checkMap.get("bool")) {

                    for (int j = 2; j <= map.size(); j++) {
                        Map<Integer, String> rowMap = map.get(j);
                        Set<Integer> keys = rowMap.keySet();
                        Attribute attr = new Attribute();
                        for (Integer key : keys) {
                            //第一行的值
                            value = firstRowMap.get(key);
                            //除去第一行以外的值
                            colValue = rowMap.get(key);
                            if ("属性名称".equals(value)) {
                                attr.setAttrName(colValue.trim());
                            } else if ("属性数据类型".equals(value)) {
                                attr.setDataType(typeMap.get(colValue.trim()));
                                dataType = colValue;
                            } else if ("属性长度".equals(value)) {
                                if ("字符".equals(dataType) || "整数".equals(dataType)) {
                                    attr.setAttrLength(colValue.trim());
                                    attr.setAttrZs(Integer.parseInt(colValue.trim()));
                                    attr.setAttrXs(0);
                                }
                                if ("小数".equals(dataType)) {
                                    attr.setAttrLength(colValue.trim());
                                    String[] zxs = colValue.split(",");
                                    attr.setAttrZs(Integer.parseInt(zxs[0].trim()));
                                    attr.setAttrXs(Integer.parseInt(zxs[1].trim()));
                                }
                                if ("日期".equals(dataType) || "文件域".equals(dataType) || "文本域".equals(dataType)) {
                                    attr.setAttrLength(null);
                                    attr.setAttrZs(0);
                                    attr.setAttrXs(0);
                                }
                            } else if ("属性描述".equals(value)) {
                                attr.setAttrDesc(colValue.trim());
                            }
                        }
                        maxCol = getColumnIndex(modelId, maxCol);
                        attr.setAttrColumn(maxCol);
                        attr.setModelId(modelId);
                        rst.add(attr);
                    }
                } else {
                    bool = false;
                    sb.append((String) checkMap.get("error"));
                }
            } else {
                bool = false;
                sb.append("@@----------错误列表-------------");
                sb.append((String) sameMap.get("err"));
            }
        }
        result_map.put("error", sb.toString());
        result_map.put("bool", bool);
        result_map.put("list", rst);
        return result_map;
    }

    private Map<String, Object> check(Map<Integer, Map<Integer, String>> map, Map<Integer, String> firstRowMap, String modelId) {
        Map<String, Object> result_map = new HashMap<>();
        boolean bool = true;
        StringBuffer sb = new StringBuffer();
        String value = null;
        String colValue = null;
        String dataType = null;
        for (int j = 2; j <= map.size(); j++) {
            sb.append("@@-----------第【" + j + "】行错误列表-------------");
            Map<Integer, String> rowMap = map.get(j);//获取一行数据
            Set<Integer> keys = rowMap.keySet();

            for (Integer key : keys) {
                //第一行的值
                value = firstRowMap.get(key);
                //除去第一行以外的值
                colValue = rowMap.get(key);
                if ("属性名称".equals(value)) {
                    if (StringUtils.isBlank(colValue)) {
                        sb.append("@@【属性名称】不能为空!");
                        bool = false;
                    } else {
                        Map<String, Object> cond = new HashMap<>();
                        cond.put("modelId", modelId);
                        cond.put("attrName", colValue.trim());
                        int count = attributeDao.checkAttrName(cond);
                        if (count != 0) {
                            sb.append("@@此属性名称【" + colValue + "】和本模型已存在的属性名称重复!");
                            bool = false;
                        }
                    }
                } else if ("属性数据类型".equals(value)) {
                    //数据类型
                    if (StringUtils.isBlank(colValue)) {
                        sb.append("@@【属性数据类型】不能为空!");
                        bool = false;
                    }
                    dataType = colValue;
                } else if ("属性长度".equals(value)) {
                    if ("字符".equals(dataType) || "整数".equals(dataType)) {
                        if (StringUtils.isBlank(colValue)) {
                            sb.append("@@【属性长度】不能为空!");
                            bool = false;
                        } else {
                            //	colValue =colValue.replaceAll(".0+?$", "");
                            Pattern pattern = Pattern.compile("^\\+?[1-9][0-9]*$");
                            Matcher isNum = pattern.matcher(colValue.trim());
                            if (!isNum.matches()) {
                                sb.append("@@【属性长度】只能填写纯数字且为整数!");
                                bool = false;
                            }
                        }
                    }
                    if ("小数".equals(dataType)) {
                        if (StringUtils.isBlank(colValue)) {
                            sb.append("@@【属性长度】不能为空!");
                            bool = false;
                        } else {
                            Pattern pattern = Pattern.compile("^([0-9]+,)+[0-9]+$");
                            Matcher isNum = pattern.matcher(colValue);
                            if (!isNum.matches()) {
                                sb.append("@@小数类型【属性长度】格式不正确!");
                                bool = false;
                            }
                        }
                    }
                }
            }
        }
        result_map.put("bool", bool);
        result_map.put("error", sb.toString());
        return result_map;
    }

    /**
     * 校验Excel里是否有相同的属性名称
     */
    private Map<String, Object> check_same(Map<Integer, Map<Integer, String>> sx_map) {
        Map<String, Object> result_map = new HashMap<>();
        Map<String, String> map = new HashMap<String, String>();
        boolean bool = true;
        StringBuilder sb = new StringBuilder();
        for (int i = 2; i <= sx_map.size(); i++) {
            Map<Integer, String> hmap = sx_map.get(i);
            if (!MapUtils.isEmpty(hmap)) {
                String value = hmap.get(1);
                StringBuilder sbb = new StringBuilder();
                sbb.append(1 + "@@" + value);

                if (map.containsKey(sbb.toString())) {
                    String ss = map.get(sbb.toString()).concat("," + i);
                    map.put(sbb.toString(), ss);
                } else {
                    map.put(sbb.toString(), i + "");
                }
            }
        }

        if (map.size() > 0) {
            Iterator<String> itt = map.keySet().iterator();
            while (itt.hasNext()) {
                String cc = itt.next();
                if (map.get(cc).contains(",")) {
                    result_map.put("err", sb.append(
                            "@@第【" + map.get(cc) + "】行属性名称重复").toString());
                }

            }

        }

        if (result_map.size() > 0) {
            bool = false;
        }
        result_map.put("bool", bool);
        return result_map;
    }

    /**
     * 插入
     */
    private void insert_sx(List<Attribute> attrLst, String modelId) {
        int batchCount = 200;// 每批commit的个数
        int batchLastIndex = batchCount;// 每批最后一个的下标
        if (attrLst.size() < batchCount) {
            attributeDao.insertAttributes(attrLst);
        } else {
            for (int index = 0; index < attrLst.size(); ) {
                List<Attribute> partRes = attrLst.subList(index, batchLastIndex);
                attributeDao.insertAttributes(partRes);
                index = batchLastIndex;// 设置下一批下标
                batchLastIndex = index + (batchCount);//15 20 20  21
                if (batchLastIndex > attrLst.size()) {
                    batchLastIndex = attrLst.size();
                }
            }
        }

        Model model = modelDao.selectByPk(modelId);
        String isCreateTable = model.getIsTableCreate() + "";

        if ("1".equals(isCreateTable)) { //已经创建了表 更新表
            cacheUtil.removeElement(modelId);
            List<String> sqlLst = new ArrayList<String>();
            StringBuffer columns = new StringBuffer();
            for (Attribute attribute : attrLst) {
                StringBuffer alertTableSb = new StringBuffer();
                StringBuffer alertUpdateTableSb = new StringBuffer();

                columns.append("'" + attribute.getAttrColumn() + "',");
                alertTableSb.append("alter table T_").append(attribute.getModelId()).append(" add " + attribute.getAttrColumn() + " " +
                        "VARCHAR2(" + dbLength(attribute) + ")");
                alertUpdateTableSb.append("alter table T_").append(attribute.getModelId() + "_update").append(" add " + attribute.getAttrColumn() + " " +
                        "VARCHAR2(" + dbLength(attribute) + ")");

                String modelType = model.getModelType();
                if ("0".equals(modelType)) { //主数据类型
                    StringBuffer alertDisTableSb = new StringBuffer();
                    alertDisTableSb.append("alter table T_").append(attribute.getModelId() + "_dis").append(" add " + attribute.getAttrColumn() + " " +
                            "VARCHAR2(" + dbLength(attribute) + ")");
                    sqlLst.add(alertDisTableSb + "");
                }
                sqlLst.add(alertTableSb + "");
                sqlLst.add(alertUpdateTableSb + "");
            }
            StringBuffer updateConfig = new StringBuffer();
            updateConfig.append("insert into AM_ATTR_CONFIG (id, model_id, attr_id, attr_type, SHOW_ORDER, GROUP_ORDER, GROUP_ID) "
                    + "select AM_ATTR_CONFIG_SEQ.nextval, tmp.*, 100, 0, ''  from ( "
                    + "select model_id, id, data_type from AM_ATTRIBUTE where model_id = " + modelId + " and attr_column in (" + columns.substring(0, columns.length() - 1) + ") order by id ) tmp ");

            sqlLst.add(updateConfig + "");
            jdbcDao.executeSqlList(sqlLst, true);
        }


    }

    /**
     * <p>TODO 模型复制功能</p>
     *
     * @author : xiaoliu
     * @date :2017年3月22日上午9:28:39
     */

    @Override
    public int copyAttrubute(Map<String, Object> param) {
        int result = 0;
        result = attributeDao.copyAttrubute(param);
        return result;
    }
}
